﻿using System;
using System.Collections.Generic;
using Network;
using Framework;
using GameProtocols;

public class VisualEntityManager : Singleton<VisualEntityManager>
{
    Dictionary<int, ObjHandle<VisualEntity>> allEntities = new Dictionary<int, ObjHandle<VisualEntity>>();
    public Action<ObjHandle<VisualEntity>> OnCreateMainCharacter;
    public Action OnDestroyMainCharacter;

    public ObjHandle<VisualEntity> MyEntity = ObjHandle<VisualEntity>.NULL;

    public VisualEntityManager()
    {
    }

    public void Destroy()
    {
        foreach (var item in allEntities.Values)
        {
            if (item.IsValid)
            {
                if (item.handle.playerID == PlayerManager.Instance.MyPlayerID)
                {
                    if (OnDestroyMainCharacter != null)
                        OnDestroyMainCharacter();
                }

                item.handle.Destroy();
                if (item.handle != null)
                    SimplePool.Despawn(item.handle.gameObject);
                item.Release();
            }
        }
        allEntities.Clear();

    }

    public ObjHandle<VisualEntity> GetEntity(int EntityID)
    {
        if (allEntities == null)
            return ObjHandle<VisualEntity>.NULL;
        if (allEntities.ContainsKey(EntityID))
            return allEntities[EntityID];
        else
            return ObjHandle<VisualEntity>.NULL;
    }

    struct L2VCall
    {
        public int mEntityID;
        public int mOpCode;
        public object[] mContent;
    }

    Queue<L2VCall> mL2VCallQueue= new Queue<L2VCall>();

    public void SendMsg(int entityID, int opcode, params object[] content)
    {
        mL2VCallQueue.Enqueue(new L2VCall
        {
            mEntityID = entityID,
            mOpCode = opcode,
            mContent = content
        });
    }

    public void DispatchMsg()
    {
        while(mL2VCallQueue.Count > 0)
        {
            var item = mL2VCallQueue.Dequeue();
            var visual = GetEntity(item.mEntityID);
            if (visual.IsValid == false)
                continue;
            visual.handle.DispatchMsg(item.mOpCode, item.mContent);
        }
    }

    public void CreateEntity(int characterID, int entityID, long playerID)
    {
        ObjHandle<VisualEntity> vEntity = VisualEntity.InitVisualEntitiy(characterID, entityID, playerID);
        allEntities.Add(vEntity.handle.entityID, vEntity);
        if (playerID == PlayerManager.Instance.MyPlayerID)
        {
            if(OnCreateMainCharacter != null)
                OnCreateMainCharacter.Invoke(vEntity);
            MyEntity = vEntity;
        }
    }

    public void DelEntity(int entityID)
    {
        ObjHandle<VisualEntity> vEntity = GetEntity(entityID);
        if (vEntity.IsValid == false)
            return;
        long playerID = vEntity.handle.playerID;
        allEntities.Remove(entityID);
        if (vEntity.IsValid)
        {
            if (playerID == PlayerManager.Instance.MyPlayerID)
                OnDestroyMainCharacter.Invoke();

            
            vEntity.handle.Destroy();
            vEntity.handle.enabled = false;
            SimplePool.Despawn(vEntity.handle.gameObject);
            vEntity.Release();
        }
    }

    public List<ObjHandle<VisualEntity>> GetAllPlayerEntity()
    {
        List<ObjHandle<VisualEntity>> list = new List<ObjHandle<VisualEntity>>();
        foreach (var var in allEntities)
        {
            list.Add(var.Value); 
        }
        return list;
    }
    #region Dispatch

    #endregion
}
